package com.sdy.dcsb.web.controller.inboundservice;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sdy.dcsb.biz.model.EsbInboundH5;
import com.sdy.dcsb.biz.model.EsbInboundMain;
import com.sdy.dcsb.biz.service.EsbInboundH5Service;
import com.sdy.dcsb.biz.service.EsbInboundMainService;
import com.sdy.dcsb.web.controller.inboundservice.util.ProcessorUtil;
import com.sdy.dcsb.web.controller.inboundservice.util.ServiceUtil;
import com.sdy.dcsb.web.controller.inboundservice.util.ServletUtil;
import com.sdy.mvc.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.soap.MimeHeaders;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.springframework.util.StringUtils.isEmpty;

/**
 * <p>
 * h5类接口
 * </p>
 *
 * @author fb
 * @since 2020/01/03
 */
@Slf4j
@Controller
@RequestMapping("/DCSBWeb/h5servlets")
@Api(tags = "h5类接口")
public class H5ServiceController extends BaseController {

    @Autowired
    private ProcessorUtil processorUtil;
    @Autowired
    private EsbInboundMainService esbInboundMainService;
    @Autowired
    private EsbInboundH5Service esbInboundH5Service;

    private static String base64Pattern = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
    private static Pattern p = Pattern.compile(base64Pattern);

    /**
     * 获取请求的接口编码和版本及坐标参数
     * @param code ,编码和版本
     * @return
     */
    @RequestMapping("/{code}/{sign}/{z}/{y}/{x}")
    @ResponseBody
    @ApiOperation("获取请求的接口编码和版本及坐标参数")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "code", value = "编码和版本"),
            @ApiImplicitParam(dataType = "String", name = "sign", value = "标志"),
            @ApiImplicitParam(dataType = "String", name = "z", value = "z"),
            @ApiImplicitParam(dataType = "String", name = "y", value = "y"),
            @ApiImplicitParam(dataType = "String", name = "x", value = "x"),
    })
    public void getCode(HttpServletRequest request, @PathVariable("code") String code, @PathVariable("sign") String sign,
                          @PathVariable("z") String z, @PathVariable("y") String y, @PathVariable("x") String x,
                          HttpServletResponse response) throws IOException{
        long requestTime = System.currentTimeMillis();
        String responseMsg = null;
        String servcode = null;
        String servversion = null;
        String urladd = null;
        String requestIp = null;
        String requestHttpType = null;
        String queryString = null;
        MimeHeaders headers = null;
        HashMap<String, String> map = new HashMap<String, String>();
        String serviceUrl = request.getRequestURL().toString();
        String address = serviceUrl.substring(serviceUrl.indexOf("/")+2);
        String[] array = address.split("/");
        // 获取请求url中的ip+端口
        String ipAndPort = array[0];
        try{
            Map<String, String> servcodeMap = ServiceUtil.getServcode(code);
            servcode = servcodeMap.get("servcode");
            servversion = servcodeMap.get("servversion");
            urladd = "/" + sign + "/" + z + "/" + y + "/" + x;
            requestIp = ServletUtil.getIpAddr(request);
            requestHttpType = request.getMethod();
            queryString = request.getQueryString();
            Map<String, String> queryStringMap = ServiceUtil.getQueryString(queryString, responseMsg);
            if(queryStringMap.containsKey("code")) {
                responseMsg = queryStringMap.get("responseMsg");
                throw new Exception(responseMsg);
            }else {
                queryString = queryStringMap.get("queryString");
            }
            map = ServletUtil.headerMap(request);
            headers = ServletUtil.getHeaders(request);
            String[] reqLengths = headers.getHeader("Content-Length");
            long reqLength = 0;
            if(null != reqLengths && reqLengths.length > 0) {
                reqLength = Integer.parseInt(reqLengths[0]);
            }
            // 获取请求的字符集
            String reqCharset = null;
            String contentType = null;
            contentType = request.getContentType();
            Map<String, String> contentTypeMap = ServiceUtil.getContentType(contentType, request);
            contentType = contentTypeMap.get("contentType");
            reqCharset = contentTypeMap.get("reqCharset");
            String requestMsg = "";
            // 表单http请求
            Map<String, String> requestMsgMap = ServiceUtil.getRequestMsg(contentType, request, reqCharset);
            if(requestMsgMap.containsKey("code")) {
                responseMsg = requestMsgMap.get("responseMsg");
                throw new Exception(responseMsg);
            }else {
                requestMsg = requestMsgMap.get("requestMsg");
            }
            // 把头信息放到queryString里
            if(isEmpty(queryString)) {
                queryString = contentType;
            }
            if(reqLength == 0) {
                reqLength = requestMsg.length();
            }
            if(!queryString.equals(contentType)){
                reqLength = reqLength + queryString.length();
            }
            // 访问标准服务
            responseMsg = processorUtil.doProcess(servcode, servversion, requestIp, requestHttpType, Integer.valueOf(String.valueOf(reqLength)),
                    queryString, contentType, requestMsg, reqCharset, requestTime, "3", ipAndPort, map, urladd);
            Matcher m = p.matcher(responseMsg);
            if(!m.matches()){
                response.setContentType("text/html; charset=utf-8");
                response.getOutputStream().write(responseMsg.getBytes("UTF-8"));
            }else {
                QueryWrapper<EsbInboundMain> esbInboundMainWrapper = new QueryWrapper<>();
                esbInboundMainWrapper.eq("servcode", servcode);
                esbInboundMainWrapper.eq("servversion", servversion);
                List<EsbInboundMain> esbInboundMainWrapperResult = esbInboundMainService.list(esbInboundMainWrapper);
                EsbInboundH5 esbInboundH5Result = esbInboundH5Service.getById(esbInboundMainWrapperResult.get(0).getServiceid());
                if("H".equals(esbInboundH5Result.getTarType())) {
                    response.setContentType("text/html; charset=utf-8");
                    response.getOutputStream().write(responseMsg.getBytes("UTF-8"));
                }else {
                    response.setContentType("image/png");
                    Base64.Decoder decoder = Base64.getDecoder();
                    response.getOutputStream().write(decoder.decode(responseMsg));
                }
            }
        }catch (Throwable e){
            response.setContentType("text/html; charset=utf-8");
            response.getOutputStream().write(responseMsg.getBytes("UTF-8"));
        }
    }
}
